﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Data;

using Shared;
using JoltEnvironment.Sql;

namespace WorldServer
{
    public partial class Client
    {
        #region Handler

        /// <summary>
        /// Defines on what position the header is on.
        /// </summary>
        private const int HeaderPoint = 17;

        /// <summary>
        /// Handles an incoming packet for the client.
        /// </summary>
        /// <param name="Packet">Packet to be handled.</param>
        public void HandlePacket(DataPacket Packet)
        {
            if (this.Remains != null)
            {
                byte[] Buffer = new byte[this.Remains.Length + Packet.Buffer.Length];

                Array.Copy(this.Remains, 0, Buffer, 0, this.Remains.Length);
                Array.Copy(Packet.Buffer, 0, Buffer, 0, Packet.Buffer.Length);

                this.Remains = null;
            }
            else
            {
                if (Packet.Size < Client.HeaderPoint)
                {
                    this.Destruct("Invalid packet length.");
                    return;
                }
            }

            if (!Packet.VerifyHeaders(this.SessionKey))
            {
                Remains = Packet.Buffer;
            }
            else
            {
                Packet.Pointer = Client.HeaderPoint;
                int Header = Packet.ReadInt32();

                this.PacketTick = (uint)Tick.GetTickCount();

                if ((Packet.Size - Client.HeaderPoint) >= 4)
                {
                    int OldPointer = Packet.Pointer;
                    Packet.Pointer = Packet.Size - 4;

                    this.ClientState = Packet.ReadInt32();

                    Packet.Pointer = OldPointer;
                }
                
                Program.Logger.DumpPacket(Header, Packet);

                if (!Program.WorldManager.PacketHandler.HandleDataPacket(this, Packet, (uint)Header))
                {
                    this.Write("Invalid packet header received: 0x{0}", Header.ToString("X8"));
                }
            }
        }

        #endregion

        #region Incoming Handlers

        [HandlesPacket(MessageHeaders.IN_SPAWN_PLAYER)]
        public void HandlePlayerSpawn(DataPacket Packet)
        {
            #region User data and verification.

            byte[] AuthKey = Packet.ReadBytes(16);
            int PlayerID = Packet.ReadInt32();
            Packet.ReadInt64(); // Unknown.
            Packet.ReadInt64(); // Unknown.
            int WorldID = Packet.ReadInt32();
            Packet.ReadInt32(); // Unknown.
            Packet.ReadInt64(); // Unknown.
            string PlayerName = Packet.ReadString();
            string Username = Packet.ReadString();
            string Password = Packet.ReadString();

            if (WorldID != Program.WorldManager.ID)
            {
                this.Destruct("Invalid world id provided upon login.");
                return;
            }

            DataRow Data = null;

            using (SqlDatabaseClient Client = Program.DatabaseManager.GetClient())
            {
                Client.AddParameter("name", PlayerName);
                Client.AddParameter("id", PlayerID);
                Client.AddParameter("username", Username);
                Client.AddParameter("password", Password);

                Data = Client.ReadDataRow("SELECT * FROM character_tbl LEFT JOIN account_tbl ON character_tbl.account_id=account_tbl.id WHERE account_tbl.username=@username AND account_tbl.password=@password AND character_tbl.name=@name AND character_tbl.id=@id;");
            }

            if (Data == null)
            {
                this.Destruct("Invalid user data provided upon login.");
                return;
            }

            #endregion

            
        }

        #endregion
    }
}
